package com.softcits.auth2;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

@Configuration
@EnableAuthorizationServer
@ConfigurationProperties(prefix = "oauth2")
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private Logger logger = LoggerFactory.getLogger(AuthorizationServerConfiguration.class);

    private String clientid;
    private String secret;
    private String tokenValidityInSeconds;
    private String filterOrder;

    public String getClientid() {
        return clientid;
    }

    public void setClientid(String clientid) {
        logger.debug("set clientid....");
        this.clientid = clientid;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public String getTokenValidityInSeconds() {
        return tokenValidityInSeconds;
    }

    public void setTokenValidityInSeconds(String tokenValidityInSeconds) {
        this.tokenValidityInSeconds = tokenValidityInSeconds;
    }

    public String getFilterOrder() {
        return filterOrder;
    }

    public void setFilterOrder(String filterOrder) {
        this.filterOrder = filterOrder;
    }

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource ;

    @Bean
    public TokenStore tokenStore(){

        //这个是基于JDBC的实现，令牌（Access Token）会保存到数据库
        return new JdbcTokenStore(dataSource);
    }
    
    @Autowired
    @Qualifier("softcitsUser")
    private UserDetailsService userService;

    @Autowired
    @Qualifier("authenticationManagerBean")//认证方式
    private AuthenticationManager authenticationManager ;
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.userDetailsService(this.userService)
                .authenticationManager(authenticationManager) ;
    }

    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory() // 使用in-memory存储
                .withClient(this.clientid)//client_id用来标识客户的Id
                .scopes("read", "write") //允许授权范围
                .authorities("ROLE_ADMIN","ROLE_USER")//客户端可以使用的权限
                .authorizedGrantTypes("password", "refresh_token")//允许授权类型
                .secret(this.secret)//secret客户端安全码
                .accessTokenValiditySeconds(Integer.parseInt(this.tokenValidityInSeconds));

    }
}